#!/usr/bin/env bash
########################
# The default pulseaudio server address is 127.0.0.1
# 本机默认音频服务地址为127.0.0.1,默认端口为4713。
# Die Standard-Audiodienst Adresse dieses Geräts lautet 127.0.0.1
export PULSE_SERVER=127.0.0.1

# The default resolution is 1440x720, it is recommended that you adjust it according to the screen ratio.
# 默认分辨率为1440x720,您可以修改为其他值,例如3840x2160,2880x1440,2400x1200,1920x1080,1920x960,720x1140,1280x1024,1280x960,1280x720,1024x768,800x680等等。
# Die Standardauflösung ist 1440x720
VNC_RESOLUTION=1440x720

# If the display number=2,then vnc port=5902.
# 若显示编号为2,则vnc端口为$((5900+2))=5902。
# Wenn die Anzeigenummer 2 ist, ist der vnc-Port 5902
VNC_DISPLAY=2
RFB_PORT=$((5900 + VNC_DISPLAY))

# You can specify a VNC user. The current user is $(whoami)
# 您可以指定VNC用户，例如root或ubuntu，默认为$(whoami)
# Sie können einen VNC-Benutzer angeben
VNC_USER=$(whoami)

# Only allow connections from localhost.Default is false.
# 当此变量的值为true时，仅允许本机连接；为false时，允许局域网连接。默认为false
# Wenn dieser Parameterwert "true" ist, lassen Sie nur Verbindungen von localhost zu
VNC_LOCALHOST=false

# You can choose tiger or tight.
# 服务端可选tiger或tight。
# Sie können "tiger" oder "tight" wählen.
VNC_SERVER=tiger

# Zlib compression level for ZRLE encoding (it does not affect Tight encoding). Acceptable values are between 0  and  9.
# 压缩级别,可选0至9,默认为0。
# Die Standardkomprimierungsstufe für zlib ist 0
ZLIB_LEVEL=0

# Specify the pixel depth in bits of the desktop to be created. Default is 24.
# 色彩/位/像素深度，可选16、24或32,默认为24，建议选用16或者24。
# Die Standardpixeltiefe beträgt 24
PIXEL_DEPTH=24

# Always treat incoming connections as shared, regardless of the client-specified setting. Default is true.
ALWAYS_SHARED=true

DBUS_ENABLED=true
# If the value is true, "sudo service dbus start" will be executed automatically every time.
AUTO_START_DBUS=true

# Before each start, vnc will be automatically stopped.
# If the value is true, then "startvnc" => "restart vnc"
AUTO_STOP_VNC=true

# If you are using arch and cannot start dbus-daemon, then change the value to true.
# TMOE_CHROOT=false
###################
if [[ ${VNC_USER} != $(whoami) && -n ${VNC_USER} ]]; then
    if grep -q "^${VNC_USER}:" /etc/passwd; then
        CURRENT_HOME=$(grep "^${VNC_USER}:" /etc/passwd | awk -F ':' '{print $6}' | head -n 1)
        HOME=${CURRENT_HOME}
    else
        printf "\033[33m%s\033[m %s \033[32m%s \033[m%s\n" "WARNING！" "You should type" "useradd -m ${VNC_USER}" "to create it."
        unset VNC_USER
    fi
    #sudo su - ${VNC_USER} -c "startvnc" || su - ${VNC_USER} -c "startvnc"
    #return 0
fi
###################
X509_VNC_ENABLED=false
#Default is false.
X509_KEY=${HOME}/.vnc/x509-key.pem
#Path to the key of the X509 certificate in PEM format
X509_CERTIFICATE=${HOME}/.vnc/x509-cert.pem
#Path to the X509 certificate in PEM format
###################
RED=$(printf '\033[31m')
GREEN=$(printf '\033[32m')
YELLOW=$(printf '\033[33m')
BLUE=$(printf '\033[34m')
PURPLE=$(printf '\033[35m')
# CYAN=$(printf '\033[36m')
RESET=$(printf '\033[m')
# BOLD=$(printf '\033[1m')
printf "${GREEN}%s ${YELLOW}%s${RESET} %s\n" "Starting" "vnc server" "..."
printf "%s\n" "The current ${BLUE}vnc port${RESET} is ${YELLOW}${RFB_PORT}${RESET}, and vnc address is ${GREEN}localhost${YELLOW}:${RFB_PORT}${RESET}"
export USER=${VNC_USER}
[[ ${AUTO_STOP_VNC} != true ]] || stopvnc -no-stop-dbus 2>/dev/null
###################
TMOE_LINUX_DIR='/usr/local/etc/tmoe-linux'
TMOE_GIT_DIR="${TMOE_LINUX_DIR}/git"
TMOE_TOOL_DIR="${TMOE_GIT_DIR}/share/old-version/tools"
TMOE_VNC_PASSWD_FILE="${HOME}/.vnc/passwd"
XSESSION_FILE='/etc/X11/xinit/Xsession'
TMOE_LOCALE_FILE="${TMOE_LINUX_DIR}/locale.txt"
TIGERVNC_CONFIG_FILE='/etc/tigervnc/vncserver-config-tmoe'
TIGERVNC_VIEWER_WIN10='/mnt/c/Users/Public/Downloads/tigervnc/vncviewer64.exe'
# TIGERVNC_BIN='/usr/bin/tigervncserver'
unset TMOE_WSL
###################
check_tmoe_locale() {
    if [ -e "${TMOE_LOCALE_FILE}" ]; then
        TMOE_LANG=$(head -n 1 ${TMOE_LOCALE_FILE})
    else
        TMOE_LANG="zh_CN.UTF-8"
    fi
    export LANG="${TMOE_LANG}"
}
###################
check_current_user_name_and_group() {
    CURRENT_USER_NAME=$(grep "${HOME}" /etc/passwd | awk -F ':' '{print $1}' | head -n 1)
    CURRENT_USER_GROUP=$(grep "${HOME}" /etc/passwd | awk -F ':' '{print $4}' | cut -d ',' -f 1 | head -n 1)
    if [ -z "${CURRENT_USER_GROUP}" ]; then
        CURRENT_USER_GROUP=${CURRENT_USER_NAME}
    fi
}
###################
fix_vnc_permissions() {
    CURRENT_USER_VNC_FILE_PERMISSION=$(ls -l "${TMOE_VNC_PASSWD_FILE}" | awk -F ' ' '{print $3}')
    case ${CURRENT_USER_VNC_FILE_PERMISSION} in
    "${CURRENT_USER_NAME}") ;;
    *)
        cd "${HOME}" || exit
        VNC_FILE=".vnc"
        for i in ".ICEauthority" ".Xauthority" ".config"; do
            [[ ! -e "${i}" ]] || VNC_FILE="${VNC_FILE} ${i}"
        done
        sudo -E chown -Rv "${CURRENT_USER_NAME}":"${CURRENT_USER_GROUP}" ${VNC_FILE} || su -c "chown -Rv ${CURRENT_USER_NAME}:${CURRENT_USER_GROUP} ${VNC_FILE}"
        unset i
        ;;
    esac
}
###################
check_wsl() {
    if [[ -r /proc/version ]]; then
        UNAME="$(head -n 1 /proc/version)"
        case "${UNAME}" in
        *Microsoft* | *microsoft*)
            export TMOE_CHROOT=true
            export TMOE_WSL=true
            source ${TMOE_LINUX_DIR}/wsl_pulse_audio
            ;;
        esac
    fi
}
set_passwd() {
    mkdir -pv ~/.config/tmoe-linux ~/.vnc
    if [[ ! -s "${TMOE_VNC_PASSWD_FILE}" ]]; then
        for i in /root/.vnc/passwd /root/.vnc/x11passwd; do
            sudo -E cp -fv ${i} ~/.vnc
        done
        if [ ! -e "${TMOE_VNC_PASSWD_FILE}" ]; then
            printf "%s\n" "${GREEN}updating${RESET} ..."
            cd ${TMOE_GIT_DIR} || exit 1
            printf "%s\n" "${GREEN}git pull ${YELLOW}--rebase --stat ${BLUE}origin master ${PURPLE}--allow-unrelated-histories${RESET}"
            case $(id -u) in
            0)
                git reset --hard origin/master
                git pull --rebase --stat origin master --allow-unrelated-histories || git rebase --skip
                ./share/old-version/tools/app/tool -passwd
                ;;
            *)
                sudo git reset --hard origin/master
                sudo git pull --rebase --stat origin master --allow-unrelated-histories
                sudo -E bash ./share/old-version/tools/app/tool -passwd
                ;;
            esac
        fi
        sudo -E chown -Rv "${CURRENT_USER_NAME}":"${CURRENT_USER_GROUP}" ~/.vnc/
    fi
}
reset_passwd() {
    if [[ ! -e ${HOME}/.vnc/passwd ]]; then
        printf "%s\n" \
            "发生错误，正在重置密码，请输入6至8位数的密码 :" \
            "Resetting the password ..." \
            "Please enter a new passwd :"
        vncpasswd
        if [[ ! -s ${HOME}/.vnc/passwd ]]; then
            x11vncpasswd
            cp ~/.vnc/x11passwd ~/.vnc/passwd
        fi
        for i in ~/.vnc/*passwd; do
            chmod -v 600 "${i}"
        done
    fi
}
remove_proot_meta_files() {
    for i in ~/.vnc/.proot*; do
        if [[ -e ${i} ]]; then
            printf "%s\n" "${GREEN}sudo ${RED}rm ${YELLOW}-fv ${BLUE}${i}${RESET}"
            rm -fv "${i}" || sudo rm -fv "${i}"
        fi
    done
}
tmoe_vnc_preconfigure() {
    check_tmoe_locale
    check_current_user_name_and_group
    set_passwd
    reset_passwd
    remove_proot_meta_files
    fix_vnc_permissions
    check_wsl
}
###################
check_vnc_ip() {
    TMOE_IP_ADDR=$(ip -4 -br -c a | awk '{print $NF}' | cut -d '/' -f 1 | grep -v '127\.0\.0\.1' | sed "s@\$@:${RFB_PORT}@")
    TMOE_IPV6_ADDR=$(ip -6 -c a | grep '/' | grep -v 'fe80::.*/64' | awk '{print $2}' | cut -d '/' -f 1 | sed "s@^@[@g;s@\$@]:${RFB_PORT}@g")
}
display_vnc_ip_addr() {
    # check_vnc_port
    check_vnc_ip
    case ${TMOE_LANG} in
    zh_*UTF-8)
        cat <<-EOF
正在启动vnc服务,${YELLOW}本机${RESET}vnc地址 ${BLUE}localhost${GREEN}:${RFB_PORT}${RESET}
${YELLOW}IPv6${RESET}地址 ${TMOE_IPV6_ADDR}
The LAN VNC address ${YELLOW}局域网${RESET}地址 ${TMOE_IP_ADDR}
EOF
        ;;
    *)
        cat <<-EOF
The ${YELLOW}local${RESET} vnc address is ${BLUE}localhost${GREEN}:${RFB_PORT}${RESET}
The ${YELLOW}IPv6${YELLOW} address is ${TMOE_IPV6_ADDR}
The ${YELLOW}LAN${RESET} vnc address is ${TMOE_IP_ADDR}
EOF
        ;;
    esac

}
###################
start_win10_tigervnc() {
    case ${TMOE_WSL} in
    true)
        cd "${HOME}" || cd /tmp || exit 1
        nohup ${TIGERVNC_VIEWER_WIN10} -PasswordFile "${TMOE_VNC_PASSWD_FILE}" localhost:${RFB_PORT} &>/dev/null &
        cd - &>/dev/null || exit 1
        ;;
    esac
}
###################
start_tmoe_xvnc() {
    case ${VNC_SERVER} in
    tight* | Tight*)
        XVNC_BIN='Xtightvnc'
        TMOE_VNC_BIN='tight'
        if [[ ! $(command -v ${XVNC_BIN}) ]]; then
            printf "%s\n" "${PURPLE}sudo ${GREEN}apt ${YELLOW}install ${BLUE}tightvncserver${RESET}"
            sudo apt install tightvncserver || su -c "apt install -y tightvncserver"
        fi
        ;;
    tiger* | Tiger* | *)
        XVNC_BIN='Xtigervnc'
        TMOE_VNC_BIN='tiger'
        [[ $(command -v ${XVNC_BIN}) ]] || XVNC_BIN='Xvnc'
        ;;
    esac
    source ${TIGERVNC_CONFIG_FILE} 2>/dev/null

    if [[ ! ${ZLIB_LEVEL} =~ ^[0-9]+$ ]]; then
        ZLIB_LEVEL=0
    elif ((ZLIB_LEVEL >= 10)); then
        ZLIB_LEVEL=9
    fi
    if [[ ! ${PIXEL_DEPTH} =~ ^[0-9]+$ ]]; then
        ZLIB_LEVEL=24
    elif ((PIXEL_DEPTH > 32)); then
        PIXEL_DEPTH=32
    fi
    #[[ $(readlink /etc/alternatives/vncserver) = "${TIGERVNC_BIN}" || $(command -v vncsession) ]]
    if [[ ${TMOE_VNC_BIN} = tiger ]]; then
        set -- "${@}" "-ZlibLevel=${ZLIB_LEVEL}"
    fi
    # In tigervnc v1.12.0, `-rfbwait` has been deprecated.
    # set -- "${@}" "-rfbwait" "30000"
    set -- "${@}" "-pn"
    if [[ -e /etc/X11/fontpath.d ]]; then
        set -- "${@}" "-fp" "catalogue:/etc/X11/fontpath.d"
    fi
    set -- "${@}" "-rfbport" "${RFB_PORT}"
    if [[ ${VNC_LOCALHOST} = true ]]; then
        set -- "${@}" "-localhost"
    fi

    if [[ ${X509_VNC_ENABLED} = true && -e ${X509_KEY} && -e ${X509_CERTIFICATE} ]]; then
        set -- "${@}" "-SecurityTypes" "X509Vnc,X509Plain,X509None,VncAuth,TLSVnc"
        set -- "${@}" "-X509Key" "${X509_KEY}"
        set -- "${@}" "-X509Cert" "${X509_CERTIFICATE}"
    fi
    if [[ ${ALWAYS_SHARED} = true ]]; then
        set -- "${@}" "-alwaysshared"
    fi
    set -- "${@}" "-a" "5"
    set -- "${@}" "-wm"
    set -- "${@}" "-geometry" "${VNC_RESOLUTION}"
    set -- "${@}" "-once"
    set -- "${@}" "-depth" "${PIXEL_DEPTH}"
    #set -- "${@}" "-deferglyphs" "16"
    set -- "${@}" "-rfbauth" "${TMOE_VNC_PASSWD_FILE}"
    set -- "${@}" "-desktop" "${desktop}"
    set -- "${@}" ":${VNC_DISPLAY}"
    set -- "${XVNC_BIN}" "${@}"
    if [[ ${VNC_USER} = $(whoami) || -z ${VNC_USER} ]]; then
        [[ -n ${XDG_RUNTIME_DIR} ]] || export XDG_RUNTIME_DIR=/tmp/runtime-${UID}
        [[ -e ${XDG_RUNTIME_DIR} ]] || mkdir -pv ${XDG_RUNTIME_DIR}
        "${@}" 2>~/.vnc/vnc.log &
    else
        #XVNC_COMMAND="${@}"
        #sudo su - ${VNC_USER} -c "${XVNC_COMMAND} &" || su - ${VNC_USER} -c "${XVNC_COMMAND} &"
        # [[ -n ${XDG_RUNTIME_DIR} ]] || export XDG_RUNTIME_DIR=/tmp/runtime-${VNC_USER}
        sudo su - "${VNC_USER}" -c '"$0" "$@" &' -- "$@" || su - "${VNC_USER}" -c '"$0" "$@" &' -- "$@"
    fi
    export DISPLAY=:${VNC_DISPLAY}

    if [[ ${VNC_USER} = $(whoami) || -z ${VNC_USER} ]]; then
        bash ${XSESSION_FILE} &>~/.vnc/x.log &
    else
        # if [[ ${VNC_USER} != root ]]; then
        #     sudo -E su ${VNC_USER} -c "export PATH=$(printf '%s\n' "${PATH}" | sed 's@:/usr/local/sbin:@:@;s@:/usr/sbin:@:@;s@:/sbin:@:@;s@/root/.zinit/polaris/bin:@@');bash ${XSESSION_FILE} &"
        #su - (X)
        #preserve environment in container
        #else
        #    sudo -E su ${VNC_USER} -c "bash ${XSESSION_FILE} &" || su ${VNC_USER} -c "bash ${XSESSION_FILE} &"
        #fi
        sudo su - "${VNC_USER}" -c "export LANG=${LANG} PULSE_SERVER=${PULSE_SERVER} TMOE_CHROOT=${TMOE_CHROOT} TMOE_PROOT=${TMOE_PROOT} DISPLAY=${DISPLAY};bash ${XSESSION_FILE} &" || su - "${VNC_USER}" -c "export LANG=${LANG} PULSE_SERVER=${PULSE_SERVER} TMOE_CHROOT=${TMOE_CHROOT} TMOE_PROOT=${TMOE_PROOT} DISPLAY=${DISPLAY};bash ${XSESSION_FILE} &"
    fi
    start_win10_tigervnc
    exit 0
}
###################
check_dbus_servcie() {
    if [[ ${AUTO_START_DBUS} = true ]]; then
        case $(id -u) in
        0) unset SUDO ;;
        *) SUDO="sudo" ;;
        esac

        if [[ -e /etc/init.d/dbus ]]; then
            printf "%s\n" "${PURPLE}sudo ${GREEN}service ${BLUE}dbus ${YELLOW}start${RESET}"
            ${SUDO} service dbus start
            ${SUDO} service dbus status | head -n 3
        else
            printf "%s\n" "${PURPLE}sudo ${GREEN}systemctl ${BLUE}start ${YELLOW}dbus${RESET}"
            case ${TMOE_CHROOT} in
            true | false) ;;
            *) ${SUDO} systemctl start dbus ;;
            esac
        fi
    fi
}
source_tmoe_dbus_daemon() {
    if [[ ${DBUS_ENABLED} = true ]]; then
        source ${TMOE_TOOL_DIR}/gui/launch_dbus_daemon
    fi
}
###################
check_vncsession() {
    if [ "$(command -v vncsession)" ]; then
        case $(id -u) in
        0)
            vncsession "$(whoami)" :${VNC_DISPLAY}
            start_win10_tigervnc
            exit 0
            ;;
        *) check_xvnc ;;
        esac
    else
        check_xvnc
    fi
}
###################
check_xvnc() {
    if [ "$(command -v Xvnc)" ]; then
        start_tmoe_xvnc
        exit 0
    fi
}
###################
tmoe_vnc_preconfigure
check_dbus_servcie
source_tmoe_dbus_daemon
display_vnc_ip_addr
#check_vncsession
check_xvnc
##########
if [[ ! $(command -v Xvnc) && ! $(command -v vncserver) ]]; then
    startx11vnc
fi
# 注: 推荐您使用startvnc, 而不是vncserver哦！startvnc在默认情况下，会比不包含参数的vncserver更流畅哦！
# It is recommended to use startvnc instead of vncserver.
